package com.acceptable.qucun.generic.config;

import com.acceptable.qucun.generic.filter.EncodingFilter;
import com.acceptable.qucun.generic.filter.RedisFilter;
import com.acceptable.qucun.generic.util.CodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StringValueResolver;

import javax.sql.DataSource;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@EnableTransactionManagement
@Configuration
public class BeanConfig implements EmbeddedValueResolverAware {
    private StringValueResolver resolver;
    @Autowired private DataSource dataSource;

    @Override
    public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {
        this.resolver = stringValueResolver;
    }

    @Bean
    public FilterRegistrationBean<EncodingFilter> encodingFilterFilterRegistrationBean(){
        FilterRegistrationBean<EncodingFilter> bean = new FilterRegistrationBean<>();
        bean.setName("encodingFilter");
        bean.setFilter(new EncodingFilter());
        bean.addInitParameter("encoding", "UTF-8");
        bean.addUrlPatterns("/**");
        return bean;
    }

    // 事务
    @Bean
    public DataSourceTransactionManager transactionManager(){
        DataSourceTransactionManager tx = new DataSourceTransactionManager();
        tx.setDataSource(dataSource);
        return tx;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<String, String> redisTemplate = new StringRedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(redisKeySerializer());
        redisTemplate.setValueSerializer(redisKeySerializer());
        redisTemplate.setHashKeySerializer(redisKeySerializer());
        redisTemplate.setDefaultSerializer(redisKeySerializer());  //其他的都是之前设置的，设置这个即可，将默认的序列化方式改成StringRedisSerializer
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean
    public RedisSerializer<?> redisKeySerializer() {
        return new StringRedisSerializer();
    }

    @Bean
    public Lock lock(){
        return new ReentrantLock();
    }

    // 线程锁
    @Bean("IOCondition")
    public Condition IOCondition(){
        return lock().newCondition();
    }

    @Bean("mainCondition")
    public Condition mainCondition(){
        return lock().newCondition();
    }

    @Bean("redisCondition")
    public Condition redisCondition(){
        return lock().newCondition();
    }
}
